<?php


class NTreeObjects{

function __construct(&$objectArr, $myId, $parentId, $rootId = null)
	{
		$this->_objects =& $objectArr;
		$this->_myId = $myId;
		$this->_parentId = $parentId;
		if (isset($rootId)) {
			$this->_rootId = $rootId;
		}
		$this->_initialize();
	}

function _initialize()
	{
		foreach (array_keys($this->_objects) as $i) {
		$_parentId=$this->_parentId;
		$_myId=$this->_myId;
		if (isset($this->_rootId))
		$_rootId=$this->_rootId;
            $key1 = (string)$this->_objects[$i]->$_myId;
            $this->_tree[$key1]['obj'] =& $this->_objects[$i];
            $key2 = (string)$this->_objects[$i]->$_parentId;
            $this->_tree[$key1]['parent'] = $key2;
            $this->_tree[$key2]['child'][] = $key1;
			if (isset($_rootId)) {
            	$this->_tree[$key1]['root'] = $this->_objects[$i]->$_rootId;
			}
        }
	}

	function &getTree()
	{
		return $this->_tree;
	}

	/**
	 * returns an object from the tree specified by its id
	 * 
	 * @param   string  $key    ID of the object to retrieve
     * @return  object  Object within the tree
	 **/
	function &getByKey($key)
	{
		return $this->_tree[$key]['obj'];
	}

	/**
	 * returns an array of all the first child object of an object specified by its id
	 * 
	 * @param   string  $key    ID of the parent object
	 * @return  array   Array of children of the parent
	 **/
	function &getFirstChild($key)
	{
		$ret = array();
		if (isset($this->_tree[$key]['child'])) {
			foreach ($this->_tree[$key]['child'] as $childkey) {
				$ret[$childkey] =& $this->_tree[$childkey]['obj'];
			}
		}
		return $ret;
	}
	/**
	 * returns an array of all child objects of an object specified by its id
	 * 
	 * @param   string     $key    ID of the parent
	 * @param   array   $ret    (Empty when called from client) Array of children from previous recursions.
	 * @return  array   Array of child nodes.
	 **/
	function &getAllChild($key, $ret = array())
	{
		if (isset($this->_tree[$key]['child'])) {
			foreach ($this->_tree[$key]['child'] as $childkey) {
				$ret[$childkey] =& $this->_tree[$childkey]['obj'];
				$children =& $this->getAllChild($childkey, $ret);
				foreach (array_keys($children) as $newkey) {
					$ret[$newkey] =& $children[$newkey];
				}
			}
		}
		return $ret;
	}

	function &getAllChildId($key, $ret = array()){
		return $this->_tree[$key]['child'];
	}
	
	/**
     * returns an array of all parent objects.
     * the key of returned array represents how many levels up from the specified object
	 * 
	 * @param   string     $key    ID of the child object
	 * @param   array   $ret    (empty when called from outside) Result from previous recursions
	 * @param   int $uplevel (empty when called from outside) level of recursion
	 * @return  array   Array of parent nodes. 
	 **/
	function &getAllParent($key, $ret = array(), $uplevel = 1)
	{
		if (isset($this->_tree[$key]['parent']) && isset($this->_tree[$this->_tree[$key]['parent']]['obj'])) {
			$ret[$uplevel] =& $this->_tree[$this->_tree[$key]['parent']]['obj'];
			$parents =& $this->getAllParent($this->_tree[$key]['parent'], $ret, $uplevel+1);
			foreach (array_keys($parents) as $newkey) {
				$ret[$newkey] =& $parents[$newkey];
			}
		}
		return $ret;
	}



}
?>